﻿

namespace AggregationGateway.Controllers
{
    using System;
    using System.Threading.Tasks;
    using AggregationGateway.ViewModels;
    using Grpc.Net.Client;
    using Microsoft.AspNetCore.Mvc;
    //using Microsoft.Extensions.Logging;
    using WeatherGrpc.Protos;
    using TrafficGrpc.Protos;
    using NLog;

    [ApiController]
    [Route("[controller]")]
    public class HomeController : ControllerBase
    {
        private static readonly ILogger _logger = LogManager.GetCurrentClassLogger();
        //private static readonly ILogger<HomeController> _logger;


        private readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly string[] Conditions = new[]
        {
            "Heavy", "Normal", "Clear"
        };

        private readonly string[] Areas = new[]
        {
            "North", "South", "East","West"
        };

        //// VS -> VS, OK
        //private static readonly string trafficUrl = "https://localhost:5001";
        //private static readonly string weatherUrl = "https://localhost:5002";

        //// VS -> Docker, OK
        //private static readonly string trafficUrl = "http://localhost:32773";
        //private static readonly string trafficUrl = "https://localhost:32774";
        //private static readonly string weatherUrl = "http://localhost:32775";
        //private static readonly string weatherUrl = "https://localhost:32776";

        //// Docker -> docker, OK
        //// Note: Using docker compose deployment, hostname is resolved to container name (Name defined in docker-compose file)
        //// TODO: Use of https (TLS) will require certificate between containers
        private static readonly string trafficUrl = "http://traffic:80";
        //private static readonly string trafficUrl = "https://traffic:443";
        private static readonly string weatherUrl = "http://weather:80";
        //private static readonly string weatherUrl = "https://weather:443";


        /// <summary>
        /// Initializes a new instance of the HomeController class
        /// </summary>
        /// <param name="logger">Logger interface</param>
        public HomeController() //(ILogger<HomeController> logger)
        {
            //_logger = logger;
        }


        [HttpGet("Condition")]
        public async Task<string> Get()
        {
            try
            {
                _logger.Info($"[INFO] Processing request for driving condition...");

                //// NOTE: Enable non-encrypted support only in development (Referenced: Microsoft eshop sample)
                AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
                AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2Support", true);

                var rng = new Random();
                var weather = new WeatherForecast
                {
                    Date = DateTime.Now.AddDays(1),
                    TemperatureC = rng.Next(-20, 55),
                    Summary = Summaries[rng.Next(Summaries.Length)]
                };

                var traffic = new Traffic
                {
                    Date = DateTime.Now.AddDays(1),
                    Area = Areas[rng.Next(Areas.Length)],
                    Condition = Conditions[rng.Next(Conditions.Length)]
                };

                using var tChannel = GrpcChannel.ForAddress(trafficUrl);
                var tClient = new TrafficChecker.TrafficCheckerClient(tChannel);
                var tReply = await tClient.CheckTrafficConditionAsync(
                    new TrafficConditionRequest { Condition = traffic.Condition });

                using var wChannel = GrpcChannel.ForAddress(weatherUrl);
                var wClient = new WeatherChecker.WeatherCheckerClient(wChannel);
                var wReply = await wClient.CheckWeatherConditionAsync(
                    new WeatherConditionRequest { Condition = weather.Summary });

                var resultMessage = "Traffic condition: " + traffic.Condition + ". Weather condition: " + weather.Summary + ". ";

                if (wReply.Message && tReply.Message)
                {
                    resultMessage += "Clear condition & clear weather";
                }
                else if (wReply.Message || tReply.Message)
                {
                    resultMessage += "Acceptable driving condition";
                }
                else
                {
                    resultMessage += "Not Acceptable driving condition";
                }

                _logger.Info($"[INFO] Output => {resultMessage}");

                return resultMessage;
            }
            catch (Exception ex)
            {
                _logger.Error(ex, $"[ERROR] Failed to call gRPC service, URL: \"{trafficUrl}\", \"{weatherUrl}\"");
                throw;
            }
            finally
            {
                //// NOTE: Enable non-encrypted support only in development (Referenced: Microsoft eshop sample)
                AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", false);
                AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2Support", false);
            }
        }

        [HttpGet("Check")]
        public async Task<string> CheckWeather()
        {
            try
            {
                //// NOTE: Enable non-encrypted support only in development (Referenced: Microsoft eshop sample)
                AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
                AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2Support", true);

                using var channel = GrpcChannel.ForAddress(weatherUrl);
                var client = new WeatherChecker.WeatherCheckerClient(channel);
                var reply = await client.CheckWeatherConditionAsync(
                    new WeatherConditionRequest { Condition = "Clear" });

                return reply.ToString();
            }
            catch (Exception ex)
            {
                _logger.Error(ex, $"[ERROR] Failed to call gRPC service, URL: \"{weatherUrl}\"");
                throw;
            }
            finally
            {
                //// NOTE: Enable non-encrypted support only in development (Referenced: Microsoft eshop sample)
                AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", false);
                AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2Support", false);
            }
        }
    }
}
